package com.google.calypso.deeplinkdemo;

import java.io.BufferedReader;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.text.util.Linkify;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.plus.Plus;

//import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;

public class MainActivity extends ActionBarActivity {

	private String childFrag = "child";

	public class Result {
		public String deepLink;
		public long timeTaken;
	}

	public class TranslateWebUrlTask extends AsyncTask<String, Void, Result> {

		TextView tView;

		public TranslateWebUrlTask() {
			Fragment fragment = (Fragment) getSupportFragmentManager()
					.findFragmentByTag(childFrag);

			tView = (TextView) fragment.getView().findViewById(
					R.id.timing_text_view);
		}

		private Result getDeepLink(String webURL) {
			try {
				long tStart = System.currentTimeMillis();
				String deepLink = getURLContent("http://externaldeeplink.appspot.com/givedeeplinkreal?weburl="
						+ webURL);
				long tEnd = System.currentTimeMillis();
				long opTime = tEnd - tStart;
				Result r = new Result();
				r.deepLink = deepLink;
				r.timeTaken = opTime;
				return r;
			} catch (Exception e) {
				return null;
			} finally {
			}
		}

		public String getURLContent(String uri) throws Exception {

			try {
				HttpClient client = new DefaultHttpClient();
				HttpGet request = new HttpGet();
				request.setURI(new URI(uri));
				HttpResponse response = client.execute(request);
				InputStream ips = response.getEntity().getContent();
				BufferedReader buf = new BufferedReader(new InputStreamReader(
						ips, "UTF-8"));

				StringBuilder sb = new StringBuilder();
				String s;
				while (true) {
					s = buf.readLine();
					if (s == null || s.length() == 0)
						break;
					sb.append(s);

				}
				buf.close();
				ips.close();
				return sb.toString();

			} finally {
				// any cleanup code...
			}
		}

		private ProgressDialog dialog = new ProgressDialog(MainActivity.this);

		protected void onPreExecute() {
			this.dialog.setMessage("Please wait");
			this.dialog.show();
		}

		protected Result doInBackground(final String... args) {
			try {
				String url = args[0];
				Result deepLink = getDeepLink(url);
				return deepLink;
			} catch (Exception e) {
				Log.e("tag", "error", e);
				return null;
			}
		}

		@Override
		protected void onPostExecute(final Result deepLink) {

			if (dialog.isShowing()) {
				dialog.dismiss();
			}
			if (deepLink != null) {
				Uri deepLinkUri = Uri.parse(deepLink.deepLink);
				tView.setText("time:" + String.valueOf(deepLink.timeTaken)
						+ "ms");

				Intent deepLinkIntent = new Intent(Intent.ACTION_VIEW,
						deepLinkUri);
				MainActivity.super.startActivity(deepLinkIntent);

			}
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new DemoFragment(), childFrag)
					.commit();
		}
	}

	@Override
	public void startActivity(Intent intent) {
		final String action = intent.getAction();
		if (action.equals(Intent.ACTION_VIEW)) {
			Uri uri = intent.getData();
			if (uri.getScheme().equals("http")
					|| uri.getScheme().equals("https")) {
				new TranslateWebUrlTask().execute(uri.toString());
			} else {
				super.startActivity(intent);
			}
		} else {
			// proceed with normal handling by the framework
			super.startActivity(intent);
		}
	}

	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
		super.onActivityResult(requestCode, resultCode, intent);
		Fragment fragment = (Fragment) getSupportFragmentManager()
				.findFragmentByTag(childFrag);
		if (fragment != null) {
			fragment.onActivityResult(requestCode, resultCode, intent);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A fragment containing a simple view.
	 */
	public static class DemoFragment extends Fragment implements
			ConnectionCallbacks, OnConnectionFailedListener {

		/* Client used to interact with Google APIs. */
		private GoogleApiClient mGoogleApiClient;

		/*
		 * A flag indicating that a PendingIntent is in progress and prevents us
		 * from starting further intents.
		 */
		private boolean mIntentInProgress;

		/* Request code used to invoke sign in user interactions. */
		private static final int RC_SIGN_IN = 0;

		public DemoFragment() {
		}

		@Override
		public void startActivity(Intent intent) {
			final String action = intent.getAction();
			if (action.equals(Intent.ACTION_VIEW)) {
				Uri uri = intent.getData();
				if (uri.getScheme() == "http" || uri.getScheme() == "https") {

				}
			}

			// proceed with normal handling by the framework
			super.startActivity(intent);
		}

		private TextView tView;
		private static long opTime = 0;
		public View rView;

		private static final Uri URI = Uri
				.parse("content://com.google.android.gsf.gservices");
		private static final String ID_KEY = "android_id";
		private static final String flixsterWebUrl = "https://www.flixster.com/movie/the-hunger-games/";
		private static final String flixsterDeepLink = "flixster://movie?id=771250004";
		private static final String imdbUrl = "http://www.imdb.com/title/tt0068646";

		private String getAndroidId(Context ctx) {
			String[] params = { ID_KEY };
			Cursor c = ctx.getContentResolver().query(URI, null, null, params,
					null);

			if (!c.moveToFirst() || c.getColumnCount() < 2)
				return null;
			return c.getString(1);

		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			rView = rootView;

			mGoogleApiClient = new GoogleApiClient.Builder(getActivity()
					.getApplicationContext()).addConnectionCallbacks(this)
					.addOnConnectionFailedListener(this).addApi(Plus.API)
					.addScope(Plus.SCOPE_PLUS_LOGIN).build();

			tView = (TextView) rootView.findViewById(R.id.url_text_view);
			String textViewContents = getResources().getString(
					R.string.text_view)
					+ "\n" + imdbUrl + "\n\n\n" + flixsterWebUrl;

			tView.setText(textViewContents);

			Linkify.addLinks(tView, Linkify.ALL);

			Button webUrlButton = (Button) rootView
					.findViewById(R.id.weburl_button);
			webUrlButton.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					Uri uri = Uri.parse(flixsterWebUrl);
					Intent intent = new Intent(Intent.ACTION_VIEW, uri);
					startActivity(intent);
				}
			});

			Button deepLinkButton = (Button) rootView
					.findViewById(R.id.deeplink_button);
			deepLinkButton.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					Uri uri = Uri.parse(flixsterDeepLink);
					Intent intent = new Intent(Intent.ACTION_VIEW, uri);
					startActivity(intent);
				}
			});

			Button translatedDeepLinkButton = (Button) rootView
					.findViewById(R.id.translated_deeplink_button);
			translatedDeepLinkButton
					.setOnClickListener(new View.OnClickListener() {

						@Override
						public void onClick(View v) {
							MainActivity a = (MainActivity) getActivity();
							a.new TranslateWebUrlTask().execute(flixsterWebUrl);
						}
					});

			com.google.android.gms.common.SignInButton signinButton = (SignInButton) rootView
					.findViewById(R.id.sign_in_button);

			signinButton.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					if (!mGoogleApiClient.isConnecting()
							&& !mGoogleApiClient.isConnected()) {
						Log.v("SIGN", "onClick, not connected");
						mSignInClicked = true;
						resolveSignInError();
					}
					setButtonVisibility();
				}
			});

			Button signoutButton = (Button) rootView
					.findViewById(R.id.sign_out_button);

			signoutButton.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					if (mGoogleApiClient.isConnected()) {
						Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
						mGoogleApiClient.disconnect();
					}
					setButtonVisibility();
				}
			});
			TextView infoView = (TextView) rView
					.findViewById(R.id.info_text_view);
			String infoViewContents = "";

			infoView.setText(infoViewContents);

			setButtonVisibility();
			return rootView;
		}

		private void setButtonVisibility() {
			Button signoutButton = (Button) rView
					.findViewById(R.id.sign_out_button);
			com.google.android.gms.common.SignInButton signinButton = (SignInButton) rView
					.findViewById(R.id.sign_in_button);
			TextView tView = (TextView) rView.findViewById(R.id.info_text_view);

			tView.setText(String.valueOf(opTime));
			if (mGoogleApiClient.isConnected()) {
				signoutButton.setVisibility(View.VISIBLE);
				signinButton.setVisibility(View.INVISIBLE);
				tView.setVisibility(View.VISIBLE);

			} else {
				signoutButton.setVisibility(View.INVISIBLE);
				tView.setVisibility(View.INVISIBLE);
				signinButton.setVisibility(View.VISIBLE);

			}
		}

		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);

		}

		@Override
		public void onStart() {
			super.onStart();
			Log.v("Sign", "onStart, calling .connect()");
			mGoogleApiClient.connect();
		}

		@Override
		public void onStop() {
			super.onStop();

			if (mGoogleApiClient.isConnected()) {
				mGoogleApiClient.disconnect();
			}
		}

		public void onActivityResult(int requestCode, int responseCode,
				Intent intent) {
			Log.v("SIGN", "onActivityResult");

			if (requestCode == RC_SIGN_IN) {
				if (responseCode != RESULT_OK) {
					mSignInClicked = false;
				}

				mIntentInProgress = false;

				if (!mGoogleApiClient.isConnecting()) {
					mGoogleApiClient.connect();
				}
			}
		}

		public void onConnected(Bundle connectionHint) {
			mSignInClicked = false;
			Log.v("SIGN", "CONNECTED!!!!!!!");

			if (mGoogleApiClient.isConnected()) {
				Log.v("SIGN", "onConnected, isConnected");

				TextView infoView = (TextView) rView
						.findViewById(R.id.info_text_view);
				String androidId = Secure.getString(getActivity()
						.getContentResolver(), Secure.ANDROID_ID);
				String infoViewContents = Plus.AccountApi
						.getAccountName(mGoogleApiClient)
						+ "  "
						+ androidId
						+ "  " + getAndroidId(getActivity());
				Log.i("ANDROIDIDDDDDD", androidId);
				infoView.setText(infoViewContents);
			} else {
				Log.v("SIGN", "onConnected, not connected");

			}
			setButtonVisibility();
		}

		public void onConnectionSuspended(int cause) {
			mGoogleApiClient.connect();
		}

		/*
		 * Track whether the sign-in button has been clicked so that we know to
		 * resolve all issues preventing sign-in without waiting.
		 */
		private boolean mSignInClicked;

		/*
		 * Store the connection result from onConnectionFailed callbacks so that
		 * we can resolve them when the user clicks sign-in.
		 */
		private ConnectionResult mConnectionResult;

		/* A helper method to resolve the current ConnectionResult error. */
		private void resolveSignInError() {
			Log.v("SIGN", "resolving errors");

			if (mConnectionResult != null && mConnectionResult.hasResolution()) {
				try {
					mIntentInProgress = true;
					Log.v("SIGN", "start resolution");

					mConnectionResult.startResolutionForResult(getActivity(),
							RC_SIGN_IN);
				} catch (SendIntentException e) {
					// The intent was canceled before it was sent. Return to the
					// default
					// state and attempt to connect to get an updated
					// ConnectionResult.
					mIntentInProgress = false;
					Log.v("SIGN", "gonna connectt now");

					mGoogleApiClient.connect();
				}
			}
			if (mConnectionResult == null) {
				Log.v("SIGN", "result is null, calling .connect()");

				mGoogleApiClient.connect();
			}
			if (mGoogleApiClient.isConnected()) {
				Log.v("SIGN", "in resolveSignInError, connected");
			}

		}

		public void onConnectionFailed(ConnectionResult result) {
			Log.v("SIGN", "CONNECTION FAILED!!");
			if (!mIntentInProgress) {
				// Store the ConnectionResult so that we can use it later when
				// the user clicks
				// 'sign-in'.
				mConnectionResult = result;

				if (mSignInClicked) {
					// The user has already clicked 'sign-in' so we attempt to
					// resolve all
					// errors until the user is signed in, or they cancel.
					Log.v("SIGN", "WILL RESOLVE ERRORS NOW!!");

					resolveSignInError();
				}
			}
		}
	}

}
